using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using UnityEditor.Animations;
using System.Linq;

public class AnimatorSceneViewEditor : ScriptableWizard
{
   
    public class Movie
    {
        //基础数值
        public float speed;
        public float time;
        public float radio;
        public float alltime;

        //计算长度数值
        public float begintime;
        public float endtime;

        //++ 每一帧加的时间,需要一直运行
        float m_deltaTime;
        float deltaTime
        {
            get
            {
                if (m_deltaTime == 0)
                {
                    m_deltaTime = Time.realtimeSinceStartup;
                    return 0;
                }

                var interval = Time.realtimeSinceStartup - m_deltaTime;
                m_deltaTime  = Time.realtimeSinceStartup;

                return interval;
            }
        }

        public bool isPaused { get; private set; }
        public bool isStop{ get; private set; }

        GUIStyle m_style;


        public System.Action stateEvent;
        public System.Action<float, float, float,float> updateEvent;

        public Movie(float speed, float begintime, float alltime)
        {
            this.speed     = speed;
            this.begintime = begintime;
            this.endtime   = alltime;
            this.alltime   = alltime;

            isPaused = true;
            isStop   = true;

            m_style                  = new GUIStyle();
            m_style.fontStyle        = FontStyle.Bold;
            m_style.normal.textColor = Color.white;
        }

        public void Play()
        {
            radio    = 0;
            isPaused = false;
            isStop   = false;
            time     = begintime;
        }

        public void Stop()
        {
            radio    = 0;
            isPaused = true;
            isStop   = true;
            time     = begintime;
        }

        public void Pause(bool isOn)
        {
            isPaused = isOn;
            isStop   = false;
        }

        //改变进度，从而改变时间
        public void ChangeRadio(float radio)
        {
            this.radio = radio;
            this.time  = radio * (endtime - begintime) + begintime;
        }

        public void ChangeAllTime(float alltime)
        {
            this.endtime = alltime;
            this.alltime = alltime;
        }

        //正常播放
        public void Update()
        {
            var delta = deltaTime;

            if (isStop) return;

            updateEvent?.Invoke(time, radio, delta, endtime);

            if (isPaused) return;

            time += speed * delta;
            radio = time / endtime;

            if (time >= endtime)
            {
                radio = 0;
                time  = begintime;
            }
        }


        bool isClip    = false;
        bool isIn      = false;
        bool isInPause = false;
    


        float ShowLabel(string label, float value)
        {
                value           = EditorGUILayout .FloatField(" ", value);
            var labelRect       = GUILayoutUtility.GetLastRect();
                labelRect.width = 60;
            GUI.Label(labelRect, label,m_style);
            return value;
        }


        public void OnCustomGUI()
        {
            editorMovie . speed   = ShowLabel("播放速度", editorMovie . speed);
            editorMovie . alltime = ShowLabel("播放长度", editorMovie . alltime);


            if (GUILayout.Button($"{(isClip ? "v" : ">")} 固定片段", m_Style))
            {
                isClip = !(isClip);
            }

            GUI.enabled = isClip;
            if (isClip)
            {
                editorMovie . begintime = ShowLabel("   起点", editorMovie . begintime);
                editorMovie . endtime   = ShowLabel("   终点", editorMovie . endtime);
            }
            else
            {
                editorMovie.endtime   = editorMovie.alltime;
                editorMovie.begintime = 0;
            }
            GUI.enabled = true;

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.BeginVertical();
            GUILayout.Space(3);
            GUILayout.Label("进度", m_Style);
            EditorGUILayout.EndHorizontal();

            var type = Event.current.type;

            editorMovie.time  = EditorGUILayout.Slider(editorMovie.time, editorMovie.begintime, editorMovie.endtime);
            editorMovie.radio = Mathf.InverseLerp(editorMovie.begintime, editorMovie.endtime,   editorMovie.time);
            editorMovie.ChangeRadio(editorMovie.radio);
            EditorGUILayout.EndHorizontal();

            if (Event.current.type == EventType.Repaint)
            {
                isIn = Contains(GUILayoutUtility.GetLastRect(), Event.current.mousePosition);
            }

            GUILayout.Space(5);

            if (type == EventType.MouseDown)
            {
                if (isIn)
                {
                    editorMovie.Pause(isInPause = true);
                    editorState.Set(1);
                }
            }

    
        }

        bool Contains(Rect rect, Vector2 pos)
        {
            return rect.Contains(pos);
        }
    }

    public class State
    {
           int           m_stateID     = -1;
           int           m_lastID      = -1;
           string[]      buttonOptions = new string[] { "运行", "暂停", "停止" };
        public System.Action<int> stateEvent;

        public void OnCustomGUI()
        {

            m_stateID      = GUILayout.Toolbar(m_stateID, buttonOptions);
            Rect barRect   = GUILayoutUtility . GetLastRect();

            if (m_lastID != m_stateID)
            {
                m_lastID  = m_stateID;
                stateEvent?.Invoke(m_stateID);
            }
        }

        //设置为stop状态
        public void SetStop()
        {
            m_stateID = 2;
            m_lastID  = m_stateID;
            stateEvent?.Invoke(m_stateID);
        }

        //设置为stop状态
        public void Set(int id)
        {
            m_stateID = id;
            m_lastID = m_stateID;
            stateEvent?.Invoke(id);
        }
    }

    public class ClipInfo
    {
        public string[] infoNames;
        public int m_clipID = 0;

        public float defaultLength;

        AnimatorStateMachine stateMachine;

        public ClipInfo(Animator mainAtr)
        {
            var    animatorController = mainAtr            . runtimeAnimatorController as AnimatorController;
            stateMachine              = animatorController . layers[0] . stateMachine;
            infoNames                 = stateMachine       . states    . Select(_ => _ . state . name) . ToArray();
            defaultLength             = stateMachine       .defaultState. motion . averageDuration + 0.1f;

            clipID = m_clipID = infoNames.ToList().FindIndex(_ => _ == stateMachine.defaultState.name);
        }

        public void OnCustomGUI()
        {
            m_clipID = EditorGUILayout.Popup(m_clipID, infoNames);

            if (m_clipID != clipID)
            {
                clipID = m_clipID;
                var state    = stateMachine        . states[m_clipID]            . state;
                editorMovie  . ChangeAllTime(state . motion .averageDuration + 0.2f);
                stateMachine . defaultState        = state;
            }
        }
    }


    public static Title    editorTitle;
    public static Movie    editorMovie;
    public static State    editorState;
    public static ClipInfo editorInfo;

    public static Vector2  viewSize;

    static int clipID = 0;

    static int animatorCount = 0;
    static int particleCount = 0;

    static Rect WindowRect;
    static GUIStyle m_Style;

    static bool isShow = false;

    static Animator mainAnimator;

    public class Title
    {
        private bool isDragging = false;
        private Vector2 offset;
        public  string title;

        public Title(string title)
        {
            this.title = title;
        }

        public void OnCustomGUI(System.Action<Rect> OnGUI)
        {

            var view = SceneView.lastActiveSceneView;

            if (view.position.size != viewSize)
            {
       
                WindowRect.position += view.position.size - viewSize;
                viewSize = view.position.size;
            }

            WindowRect = EditorGUICustom.OnDragGUI(WindowRect, ref isDragging, ref offset, OnGUI);
        }
    }



    public static void Init(AnimatorEditorInspector.ToolData data)
    {
        clipID  = 0;
        isShow  = true;

        animatorCount = data.animatorCount;
        particleCount = data.particleCount;

        var view = SceneView.lastActiveSceneView;

        var width  = 200;
        var height = 300;
        var x      = view.position.width - width;
        var y      = view.position.height - height;

        viewSize.x = view.position.width;
        viewSize.y = view.position.height;

        WindowRect = new Rect(x, y, width, height);

        mainAnimator = data.mainAnimator;

        editorInfo  = new ClipInfo(data.mainAnimator);
        editorMovie = new Movie(1, 0, editorInfo.defaultLength);
        editorTitle = new Title("编辑器");
        editorState = new State();

        EditorApplication.update += Update;
        SceneView.duringSceneGui += OnSceneGUI;

        if (editorState != null)
        {
            editorState.stateEvent += OnStateEvent;
        }

        m_Style                  = new GUIStyle();
        m_Style.fontStyle        = FontStyle.Bold;
        m_Style.normal.textColor = Color.white;
    }

    public static void Hide()
    {
        EditorApplication.update -= Update;
        SceneView.duringSceneGui -= OnSceneGUI;

        if (editorState != null)
        {
            editorState.stateEvent -= OnStateEvent;
        }
    }


 
    static void OnSceneGUI(SceneView sceneView)
    {
        GUI.skin.box.normal.textColor = new Color(0.5f, 0.8f, 1.0f, 1.0f);
        Handles.BeginGUI();

        editorTitle.OnCustomGUI((rect) =>
        {
            if (EditorGUICustom.ButtonTitle(rect, $"{(isShow ? "v" : ">")} {editorTitle.title}", TextAlignment.Left))
            {
                isShow = !isShow;

                if (isShow == false)
                {
                    editorState.SetStop();
                }
            }
        });
        Handles.EndGUI();

        if (isShow == false)
        {
            return;
        }
        Handles.BeginGUI();

        GUILayout.BeginArea(WindowRect);
        {
            EditorGUICustom.DrawBoxTitleColor("操作参数", new Color(0.5f, 0.5f, 0.5f, 0.5f), (r) =>
            {
                editorInfo.OnCustomGUI();
                editorState.OnCustomGUI();
                editorMovie.OnCustomGUI();
            });


            EditorGUICustom.DrawBoxTitleColor("有效组件", new Color(0.5f, 0.5f, 0.5f, 0.5f), (r) =>
            {
                GUILayout.Label("Particle   组件：" + particleCount, m_Style);
                GUILayout.Label("Animator组件：" + animatorCount, m_Style);
            });
        }
        GUILayout.EndArea();
        Handles.EndGUI();
    // 


       // sceneView.Repaint();
    }

    //控制播放状态
    static void OnStateEvent(int id)
    {
        if (id == 0)
        {
            if (editorMovie.isPaused)
                editorMovie.Pause(false);
            else
                editorMovie.Play();
        }
        else if (id == 1)
        {
            editorMovie.Pause(true);
        }
        else
        {
            editorMovie.Stop();
        }
    }


    static void Update()
    {
        if (mainAnimator == null)
            AnimatorEditorInspector.Close();

        editorMovie.Update();
    }
}
